'''
Author: Hugh
Date: 2022-08-24 00:17:56
LastEditors: tongyi hughtong@outlook.com
LastEditTime: 2023-06-19 23:55:08
FilePath: \TISAConsoleCtrl\net.py
Description: 

Copyright (c) 2022 by All/Terapark, All Rights Reserved. 
'''
#!/usr/bin/env python3

import socket  #导入socket套接字模块
import threading
import time
import os 
import sys

class mySocket:
    '建立socket对象'

    def __init__(self, addr = '127.0.0.1', port = 10000, handler = None) -> None:
        self.response = 0
        self.sockit = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        self.addr = (addr, port)
        self.sockit.sendto('0'.encode(), self.addr) # 发送一条空数据
        self.reciver = threading.Thread(
                    target=self.threading_recv, args=(handler,))

# 接收启动必须等到发送第一条数据后，否则无法获取到端口导致失败
    def startRecv(self):
        self.response = 1
        self.reciver.start()

    def close(self):
        self.response = 0
        try:
            self.sockit.close()
        except:
            print("Error")

    def threading_recv(self, handler):
        
        while self.response:
            try:
                data,addr=self.sockit.recvfrom(1024)
            except:
                print("socket异常关闭")
                break
            if not data:
                break
            
            if handler != None:
                handler(addr, list(data))
            else:
                print("got data from",addr, data.hex(' '))

    def localAddrGet(self) -> tuple:
        self.sockit.sendto('0'.encode(), self.addr) # 将地址更新到arp缓存中,这个0不能省，其实就是发送一个字符，如果为空的化回导致udp崩溃
        time.sleep(0.1)
        with os.popen('arp -a') as fp:
			# windows
            for line in fp:
                line = line.split()[:2]
                if line and line[0].find('接口') != -1:
                    intface = line[1]
                    if intface == self.addr[0]:
                        self.laddr = intface
                        self.lport = self.sockit.getsockname()[1]
                        return (intface, self.sockit.getsockname()[1])
                elif line and line[0] == self.addr[0]:
                    self.laddr = intface
                    self.lport = self.sockit.getsockname()[1]
                    return (intface, self.sockit.getsockname()[1])
			# linux 
        return None
        # return ("127.0.0.1", 50000)

    def sendBytes(self, buf):#十六进制数据之间空格隔开，例如："00 01 02"
        self.sockit.sendto(bytes.fromhex(buf), self.addr)
        
    def sendStr(self, buf):# 数据为字符串，例如:"00 01 02"
        self.sockit.sendto(buf.encode(), self.addr)

    def sendList(self, buf):# 数据为list类型，例如：[0x00, 0x01, 0x02]
        self.sockit.sendto(bytes(buf), self.addr)
        return buf

if __name__ == "__main__":
    target = "192.168.2.87"
    port  = 10000
    sokit = mySocket(target, port)
    sendData = None

    # if len(sys.argv) != 1:
    #     path = sys.argv[1]
    # else:
    #     path = './data/168.txt'
    # with open(path, mode = 'r', encoding = "utf-8-sig", newline="") as data:
    #     # sokit.sendBytes()
    #     senData = data.readlines()
    #     pass
    # for line in senData:
    #     # print(type(data.readline()))
    #     sokit.sendBytes(line)
    #     time.sleep(1)

    sokit.sendStr("hello")
    sokit.startRecv()
    while 1:
        pass
        time.sleep(0.1)
